package com.zw.cloud.influxdb.controller;

import com.zw.cloud.common.utils.DateTimeUtils;
import com.zw.cloud.influxdb.entity.MonitorDeviceRunStatusFlink;
import com.zw.cloud.influxdb.entity.MonitorDeviceTopDTO;
import com.zw.cloud.influxdb.service.InfluxdbQueryService;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.InfluxDB;
import org.influxdb.dto.BatchPoints;
import org.influxdb.dto.Point;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/influxdb/run-status")
public class MonitorDeviceRunStatusFlinkController {

    @Autowired
    private InfluxDB influxDBClient;
    @Autowired
    private InfluxdbQueryService influxdbQueryService;

    /**
     * 批量插入
     */
    @GetMapping("/batchInsert/{orgCode}/{deviceId}/{minusMinutes}")
    //http://localhost:10010/influxdb/run-status/batchInsert/3983D94F788342E1B0D8F52EA890D8E8/1/10
    public void batchInsert(@PathVariable String orgCode,@PathVariable String deviceId, @PathVariable Integer minusMinutes) {
        LocalDateTime now = LocalDateTime.now();
        List<MonitorDeviceRunStatusFlink> runStatusFlinkList = new ArrayList<>();
        for (int i = 0; i < minusMinutes; i++) {
            String runStatus = i % 2 == 0 ? "0" : "1";
            MonitorDeviceRunStatusFlink runStatusFlink = buildMonitorDeviceRunStatusFlink(orgCode,deviceId,runStatus, now.minusMinutes(i));
            runStatusFlinkList.add(runStatusFlink);
        }
        runStatusFlinkList.sort(Comparator.comparing(MonitorDeviceRunStatusFlink::getTime));
        BatchPoints.Builder builder = BatchPoints.builder();
        runStatusFlinkList.forEach(m -> builder.point(Point.measurementByPOJO(m.getClass()).addFieldsFromPOJO(m).build()));
        //写入
        influxDBClient.write(builder.build());
    }

    /**
     * groupBy
     */
    @GetMapping("/groupBy/{startTimeStr}/{endTimeStr}/{orgCode}")
    //http://localhost:10010/influxdb/run-status/groupBy/2024-02-28%2015:00:00/2024-02-28%2017:00:00/3983D94F788342E1B0D8F52EA890D8E8
    public List<MonitorDeviceTopDTO> groupBy(@PathVariable String startTimeStr, @PathVariable String endTimeStr, @PathVariable String orgCode){
        String sql = "SELECT SUM(runTime) as count from (\n" +
                "SELECT (endTime-startTime) as runTime,deviceId FROM monitor_device_run_status_flink WHERE time >= $startTime and time <= $endTime and orgCode = $orgCode and runStatus = '0')  \n" +
                "GROUP BY deviceId";
        LocalDateTime startTime = DateTimeUtils.parse2datetime(startTimeStr, DateTimeUtils.DATE_TIME_PATTERN);
        LocalDateTime endTime = DateTimeUtils.parse2datetime(endTimeStr, DateTimeUtils.DATE_TIME_PATTERN);
        Map<String, Object> bindParams = new HashMap<>();
        bindParams.put("startTime", startTime);
        bindParams.put("endTime", endTime);
        bindParams.put("orgCode",orgCode);
        return influxdbQueryService.queryData(sql,MonitorDeviceTopDTO.class,bindParams,"monitor_device_run_status_flink");
    }

    private MonitorDeviceRunStatusFlink buildMonitorDeviceRunStatusFlink(String orgCode, String deviceId, String runStatus,LocalDateTime localDateTime) {
        Long second = localDateTime.toEpochSecond(ZoneOffset.of("+8"));
        Instant instant = Instant.ofEpochSecond(second);

        MonitorDeviceRunStatusFlink runStatusFlink = new MonitorDeviceRunStatusFlink();
        runStatusFlink.setTime(instant);
        runStatusFlink.setOrgCode(orgCode);
        runStatusFlink.setDeviceId(deviceId);
        runStatusFlink.setCtime(second);
        runStatusFlink.setDeviceCode("004");
        runStatusFlink.setDeviceName("定型机2");
        runStatusFlink.setEndTime(second);
        runStatusFlink.setStartTime(second-60);
        runStatusFlink.setIcCard("231106222");
        runStatusFlink.setIotCode("8888");
        runStatusFlink.setRunStatus(runStatus);

        return runStatusFlink;
    }


}
